#include <poker.h>

void shuffle(struct card_t *poker)
{
    int i, j, count, n;
    
    for (i = 0; i < CARD_TOTAL; i++)
    {
        /*
         *poker[i].color = rand() % 5;
         *if (poker[i].color == KING)
         *    poker[i].num = rand() % 2;
         *else
         *    poker[i].num = rand() % 13;
         */
        n = rand() % POKER_NUM;
        poker[i].color = poker_value[n].color;
        poker[i].num = poker_value[n].num;

        for (j = 0, count = 0; j < i; j++)
        {
            if (poker[i].color == poker[j].color &&
                    poker[i].num == poker[j].num && ++count == 2)
            {
                i--;
                break;
            }
        }
    }
}

static int _tidy_num(struct card_t *poker, unsigned char *player, int color, int num, int *len)
{
    int i, j;
    int t;

    for (i = 0, j = 0; i < *len; i++)
    {
        if ((color == ASSISTANT || poker[player[i]].color == color) && 
                poker[player[i]].num == num)
        {
            t = player[i];
            player[i] = player[j];
            player[j] = t;
            j++;
        }
    }

    *len -= j;

    return j;
}

static int _tidy_color(struct card_t *poker, unsigned char *player, int color, int level, int *len)
{
    int i, j, sum = 0;

    for (i = ACE, j = 0, sum = 0; i >= THREE; i--)
    {
        if (i == level)
            continue;
        j =  _tidy_num(poker, player, color, i, len);
        player += j;
        sum += j;
    }

    return sum;
}


void tidy_card(struct tractor_t *tractor, int total, unsigned char *player)
{
    int i, j, len = total;
    int level = tractor->player[tractor->who].level;

    player += CARD_LORD_PLAYER - CARD_HAND - CARD_BOTTOM;

    player += _tidy_num(tractor->poker, player, GHOSTS, BIG_GHOST, &len);
    player += _tidy_num(tractor->poker, player, GHOSTS, SMALL_GHOST, &len);
    player += _tidy_num(tractor->poker, player, tractor->lord, level, &len);
    player += _tidy_num(tractor->poker, player, ASSISTANT, level, &len);
    player += _tidy_num(tractor->poker, player, tractor->lord, TWO, &len);
    player += _tidy_num(tractor->poker, player, ASSISTANT, TWO, &len);

    player += _tidy_color(tractor->poker, player, tractor->lord, level, &len);

    for (i = 0; i < ASSISTANT; i++)
    {
        if (i == tractor->lord) 
            continue;
        player += _tidy_color(tractor->poker, player, i, level, &len);
    }
}

void deal_card(struct tractor_t *tractor)
{
    int i, who, k;

    tractor->who = 0;   //用于测试

    memset(tractor->player[0].card, NONE, sizeof(tractor->player[0].card));
    memset(tractor->player[1].card, NONE, sizeof(tractor->player[1].card));

    if (tractor->who == -1)
        who = 0;
    else 
        who = tractor->who;


    for (i = 0, k = 0; i < CARD_TOTAL - 8; i++)
    {
        tractor->player[who].card[k] = i;

        if (k < 16)
            tractor->poker[tractor->player[who].card[k]].hide = 1;
        else if (k >= 16 && k < 32)
        {
            if (tractor->who == -1 && 
                    (tractor->poker[i].num == THREE || 
                     tractor->poker[i].color == GHOSTS))
            {
                tractor->who = who; 
                tractor->lord = tractor->poker[i].color;
            }
            else if (tractor->lord == -1 &&
                        (tractor->poker[i].num == tractor->player[tractor->who].level ||
                         tractor->poker[i].color == GHOSTS))
                tractor->lord = tractor->poker[i].color;
        }
        else
            tractor->player[who].hand_num++;

        if (++who == 2)
        {
            who = 0; 
            k++;
        }
        /*show_tractor(tractor);*/      //实现发牌动画
        /*usleep(100000);*/
    }

    //保存底牌到谁是主的玩家手中
    for (i = CARD_TOTAL - 8, k = 0; i < CARD_TOTAL; i++, k++)
    {
        tractor->poker[i].selection = 1;
        tractor->player[tractor->who].card[CARD_PLAYER + k] = i;
        tractor->player[tractor->who].hand_num++;
    }

    tidy_card(tractor, CARD_HAND + CARD_BOTTOM, tractor->player[tractor->who].card);
    tidy_card(tractor, CARD_HAND, tractor->player[!tractor->who].card);
}

//出牌规则
//1. 出牌张数必须为1张或2的倍数张
//2. 2张或2张以上必须全为对
//3. 主和副不能一起出
//4. 如果不为主，对对的花色必须相同
//5. 如果不为主，对对必须是连续的, 级牌除外连续
//6. 如果为主，大小王、主2和副主, 副2正2, 副2正A
int sell_rule(struct tractor_t *tractor, unsigned char *card, int num)
{
    int i, j;
    int count = 0;
    int lord = 0;           //判断打的牌是否有主牌
    int second = 0;         //判断打的牌是否有副牌
    int color = 0;          //判断打的牌花色是否不一样
    int level = tractor->player[tractor->who].level;
    int max = -1, min = -1; //判断打的牌中的最大值和最小值，用于判断是否连对

    if (num == 0 || (num != 1 && num % 2 != 0))
        return -1;
    if (num == 1)
        return 0;

    for (i = 0; i < num; i++)
    {
        if (tractor->poker[card[i]].color == tractor->lord ||
            tractor->poker[card[i]].num == TWO ||
            tractor->poker[card[i]].num == level ||
            tractor->poker[card[i]].color == GHOSTS)
            lord = 1; 
        else
            second = 1;

        if (max < tractor->poker[card[i]].num) 
            max = tractor->poker[card[i]].num;

        if (min > tractor->poker[card[i]].num) 
            min = tractor->poker[card[i]].num;

        if (tractor->poker[card[0]].color != tractor->poker[card[i]].color)
            color = 1;     

        for (j = 0, count = 0; j < num; j++)        //判断2张以上是否全为对对
        {
            if (tractor->poker[card[i]].color == tractor->poker[card[j]].color &&
                tractor->poker[card[i]].num == tractor->poker[card[j]].num)
                count++;
        }
        if (count != 2)
            return -1;
    }
    if ((second && lord) || (second && color)) 
        return -1;

    if (num == 2)       //如果为两张牌，直接返回
        return 0;

    /*if (lord)       //如果为主，判断特殊连对*/

    if (((level > min && level < max) && max - min != num / 2 - 1) ||
        ((level <= min || level >= max) && max - min != num / 2))
        return -1;

    return 0;
}

